using AutoMapper;
using IOA.MES.DataAccess.Entity;
using IOA.MES.DataAccess.Enum;
using IOA.MES.DataAccess.VModel;
using IOA.MES.Common;
using System;
using System.Collections.Generic;
using System.Linq;

namespace IOA.MES.Business
{
    /// <summary>
    /// 成品组件过站BOM（错误代码：111001）
    /// </summary>
    public class ProductSiteBomMgr
    {
        private MESContext mesDb = new MESContext("MES");

        /// <summary>
        /// 查询列表
        /// </summary>
        public List<VProductSiteBom> Query(int pageIndex, int pageSize, out int total, string orderNo, string workOrderNo, SiteType siteType)
        {
            IQueryable<ProductSiteBom> query = mesDb.ProductSiteBoms.AsNoTracking().Where(_ => _.SiteType == siteType && _.Valid);
            if (!string.IsNullOrWhiteSpace(workOrderNo))
            {
                query = query.Where(_ => _.WorkOrderNo == workOrderNo);
            }
            else if (!string.IsNullOrWhiteSpace(orderNo))
            {
                query = query.Where(_ => _.OrderNo == orderNo);
            }
            else
            {
                query = query.Where(_ => _.OrderNo == "" && _.WorkOrderNo == "");
            }

            total = query.Count();
            query = query.OrderByDescending(_ => _.PkId);
            var skip = (pageIndex - 1) * pageSize;
            var entities = pageSize <= 0 ? query.ToList() : query.Skip(skip).Take(pageSize).OrderByDescending(_ => _.PkId).ToList();

            return Mapper.Map<List<VProductSiteBom>>(entities);
        }

        /// <summary>
        /// 删除
        /// </summary>
        public void Delete(VProductSiteBom model)
        {
            var entity = mesDb.ProductSiteBoms.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(111001);// "数据不存在或已被删除，无法重复删除");
            }
            entity.Valid = false;
            entity.ModifyBy = model.ModifyBy;
            entity.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询全局BOM配置
        /// </summary>
        /// <param name="siteType">站点类型</param>
        /// <returns>BOM配置</returns>
        public List<VWorkOrderSiteBom> QueryGlobalBoms(SiteType siteType, string orderNo, string workOrderNo)
        {
            var categories = mesDb.ProductCategories.AsNoTracking().Where(_ => _.Level == 1 && _.Valid).Distinct().ToList();
            var siteBomsQuery = mesDb.ProductSiteBoms.AsNoTracking().Where(_ => _.Valid);
            if (!string.IsNullOrWhiteSpace(workOrderNo))
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.WorkOrderNo == workOrderNo);
            }
            else if (!string.IsNullOrWhiteSpace(orderNo))
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.OrderNo == orderNo);
            }
            else
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.OrderNo == "" && _.WorkOrderNo == "");
            }
            var siteBoms = siteBomsQuery.ToList();
            var enableBoms = categories.Where(_ => !siteBoms.Where(b => b.SiteType != siteType).Select(b => b.BomCategoryCode).Contains(_.CategoryCode, StringComparer.CurrentCultureIgnoreCase))
                .Select(_ => new VWorkOrderSiteBom
                {
                    BomCategoryCode = _.CategoryCode,
                    BomCategoryName = _.CategoryName,
                    Selected = siteBoms.Any(s => s.SiteType == siteType && string.Equals(_.CategoryCode, s.BomCategoryCode, StringComparison.CurrentCultureIgnoreCase))
                }).OrderBy(_ => _.BomCategoryName).ToList();

            return enableBoms;
        }

        /// <summary>
        /// 编辑全局BOM配置
        /// </summary>
        /// <param name="siteType">站点</param>
        /// <param name="categoryCodes">物料分类</param>
        /// <param name="@operator">操作人</param>
        public void EditGlobalBom(SiteType siteType, string orderNo, string workOrderNo, List<string> categoryCodes, int @operator)
        {
            var siteBomsQuery = mesDb.ProductSiteBoms.AsNoTracking().Where(_ => _.Valid);
            if (!string.IsNullOrWhiteSpace(workOrderNo))
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.WorkOrderNo == workOrderNo);
            }
            else if (!string.IsNullOrWhiteSpace(orderNo))
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.OrderNo == orderNo);
            }
            else
            {
                siteBomsQuery = siteBomsQuery.Where(_ => _.OrderNo == "" && _.WorkOrderNo == "");
            }
            var siteBoms = siteBomsQuery.ToList();

            var otherSiteBomProductNames = siteBoms.Where(_ => _.SiteType != siteType && categoryCodes.Contains(_.BomCategoryCode)).Select(_ => _.BomCategoryName).Distinct().ToList();
            if (otherSiteBomProductNames.Any())
            {
                throw new MultiLanBizException(111004, string.Join("、", otherSiteBomProductNames));// $"物料{string.Join("、", otherSiteBomProductCodes)}已配置在其他站点");
            }

            var categories = mesDb.ProductCategories.AsNoTracking().Where(_ => _.Valid).ToList();
            categoryCodes = categoryCodes.Where(_ => categories.Any(c => string.Equals(_, c.CategoryCode, StringComparison.CurrentCultureIgnoreCase))).ToList();

            var curSiteBoms = siteBoms.Where(_ => _.SiteType == siteType).ToList();
            var newSiteBoms = categoryCodes.Where(_ => !curSiteBoms.Select(b => b.BomCategoryCode).Contains(_, StringComparer.CurrentCultureIgnoreCase))
                .Select(_ => new ProductSiteBom
                {
                    OrderNo = orderNo,
                    WorkOrderNo = workOrderNo,
                    SiteType = siteType,
                    BomCategoryCode = _,
                    BomCategoryName = categories.FirstOrDefault(c => string.Equals(c.CategoryCode, _, StringComparison.CurrentCultureIgnoreCase))?.CategoryName ?? string.Empty,
                    CreateBy = @operator,
                    CreateTime = DateTime.Now,
                }).ToList();
            mesDb.ProductSiteBoms.AddRange(newSiteBoms);

            var disabledSiteBoms = curSiteBoms.Where(_ => !categoryCodes.Contains(_.BomCategoryCode, StringComparer.CurrentCultureIgnoreCase)).ToList();
            disabledSiteBoms.ForEach(_ =>
            {
                mesDb.ProductSiteBoms.Attach(_);
                _.Valid = false;
                _.ModifyBy = @operator;
                _.ModifyTime = DateTime.Now;
            });

            mesDb.SaveChanges();
        }
    }
}
